package com.property.cleaning.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.property.cleaning.entity.CleaningTask;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import java.time.LocalDate;
import java.util.List;

/**
 * 任务Mapper接口
 * 
 * @author Property Cleaning System
 */
@Mapper
public interface CleaningTaskMapper extends BaseMapper<CleaningTask> {

    /**
     * 分页查询任务列表
     */
    @Select("SELECT t.*, a.area_name, p.plan_name, c.real_name as cleaner_name " +
            "FROM cleaning_tasks t " +
            "LEFT JOIN areas a ON t.area_id = a.id " +
            "LEFT JOIN cleaning_plans p ON t.plan_id = p.id " +
            "LEFT JOIN cleaners cl ON t.assigned_cleaner = cl.id " +
            "LEFT JOIN users c ON cl.user_id = c.id " +
            "ORDER BY t.task_date DESC, t.priority DESC")
    IPage<CleaningTask> findTaskPage(Page<CleaningTask> page);

    /**
     * 根据日期查询任务
     */
    @Select("SELECT t.*, a.area_name, p.plan_name, c.real_name as cleaner_name " +
            "FROM cleaning_tasks t " +
            "LEFT JOIN areas a ON t.area_id = a.id " +
            "LEFT JOIN cleaning_plans p ON t.plan_id = p.id " +
            "LEFT JOIN cleaners cl ON t.assigned_cleaner = cl.id " +
            "LEFT JOIN users c ON cl.user_id = c.id " +
            "WHERE t.task_date = #{taskDate} " +
            "ORDER BY t.priority DESC, t.start_time")
    List<CleaningTask> findByTaskDate(@Param("taskDate") LocalDate taskDate);

    /**
     * 根据保洁员ID查询任务
     */
    @Select("SELECT t.*, a.area_name, p.plan_name " +
            "FROM cleaning_tasks t " +
            "LEFT JOIN areas a ON t.area_id = a.id " +
            "LEFT JOIN cleaning_plans p ON t.plan_id = p.id " +
            "WHERE t.assigned_cleaner = #{cleanerId} " +
            "AND t.task_date = #{taskDate} " +
            "ORDER BY t.start_time")
    List<CleaningTask> findByCleanerAndDate(@Param("cleanerId") Long cleanerId, 
                                            @Param("taskDate") LocalDate taskDate);

    /**
     * 查询待分配任务
     */
    @Select("SELECT t.*, a.area_name, p.plan_name " +
            "FROM cleaning_tasks t " +
            "LEFT JOIN areas a ON t.area_id = a.id " +
            "LEFT JOIN cleaning_plans p ON t.plan_id = p.id " +
            "WHERE t.assigned_cleaner IS NULL " +
            "AND t.task_date >= CURRENT_DATE " +
            "ORDER BY t.task_date, t.priority DESC")
    List<CleaningTask> findUnassignedTasks();

    /**
     * 统计任务状态
     */
    @Select("SELECT " +
            "SUM(CASE WHEN task_status = 1 THEN 1 ELSE 0 END) as pending_count, " +
            "SUM(CASE WHEN task_status = 2 THEN 1 ELSE 0 END) as in_progress_count, " +
            "SUM(CASE WHEN task_status = 3 THEN 1 ELSE 0 END) as completed_count, " +
            "SUM(CASE WHEN task_status = 4 THEN 1 ELSE 0 END) as abnormal_count, " +
            "COUNT(*) as total_count " +
            "FROM cleaning_tasks " +
            "WHERE task_date = #{taskDate}")
    TaskStatistics getTaskStatistics(@Param("taskDate") LocalDate taskDate);

    /**
     * 任务统计内部类
     */
    public static class TaskStatistics {
        private Long pendingCount;
        private Long inProgressCount;
        private Long completedCount;
        private Long abnormalCount;
        private Long totalCount;

        // Getters and Setters
        public Long getPendingCount() { return pendingCount; }
        public void setPendingCount(Long pendingCount) { this.pendingCount = pendingCount; }
        
        public Long getInProgressCount() { return inProgressCount; }
        public void setInProgressCount(Long inProgressCount) { this.inProgressCount = inProgressCount; }
        
        public Long getCompletedCount() { return completedCount; }
        public void setCompletedCount(Long completedCount) { this.completedCount = completedCount; }
        
        public Long getAbnormalCount() { return abnormalCount; }
        public void setAbnormalCount(Long abnormalCount) { this.abnormalCount = abnormalCount; }
        
        public Long getTotalCount() { return totalCount; }
        public void setTotalCount(Long totalCount) { this.totalCount = totalCount; }
    }
}